package com.service.business.borrow.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.service.business.base.dto.LoginUserSession;
import com.service.business.borrow.controller.rep.MemberBorrowConfigRep;
import com.service.business.borrow.controller.req.MemberBorrowAddReq;
import com.service.business.borrow.service.MemberBorrowService;
import com.service.business.borrow.controller.rep.MemberBorrowDetailsRep;
import com.service.business.borrow.controller.req.PageMemberBorrowReq;
import com.service.business.support.BorrowHelp;
import com.service.business.support.SessionUtil;
import com.service.business.utils.DateUtil;
import com.service.core.exception.CommonException;
import com.service.core.rest.response.CommonPageRep;
import com.service.dao.enums.CoinsEnum;
import com.service.dao.mapper.MemberBorrowMapper;
import com.service.dao.mapper.MemberMapper;
import com.service.dao.mapper.SysBorrowConfigMapper;
import com.service.dao.model.MemberBorrow;
import com.service.dao.model.SysBorrowConfig;
import com.service.utility.modelmapper.ModelMapperUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MemberBorrowServiceImpl extends ServiceImpl<MemberBorrowMapper, MemberBorrow>
	implements MemberBorrowService {
	@Autowired
	private SessionUtil sessionUtil;
	@Autowired
	private MemberBorrowMapper memberBorrowMapper;

	@Autowired
	private MemberMapper memberMapper;

	@Autowired
	private SysBorrowConfigMapper sysBorrowConfigMapper;
	@Autowired
	private BorrowHelp borrowHelp;

	@Override
	public MemberBorrowConfigRep getInitConfig(int coinsId) {
		return ModelMapperUtil.map(getBorrowConfig(coinsId),MemberBorrowConfigRep.class);
	}

	/**
	 * 用户借贷记录
	 *
	 * @param memberBorrowAddReq
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean addBorrow(MemberBorrowAddReq memberBorrowAddReq) {
		//读取系统借贷配置
		SysBorrowConfig borrowConfig = getBorrowConfig(memberBorrowAddReq.getCoinsId());

		if(borrowConfig.getInitNum().compareTo(borrowConfig.getBorrowNum().add(memberBorrowAddReq.getBorrowNum())) < 0){
			throw new CommonException(402,"系统可借出金额不够！");
		}
		Integer userId = sessionUtil.getUser().getUserId();
		//计算累计还款金额 本金+手续费
		BigDecimal monthFee = memberBorrowAddReq.getBorrowNum().multiply(borrowConfig.getMonthScale());
		BigDecimal totalReturnNum = memberBorrowAddReq.getBorrowNum().add(monthFee);

		MemberBorrow memberBorrow = new MemberBorrow();
		memberBorrow.setMemberId(userId);
		memberBorrow.setCoinsId(memberBorrowAddReq.getCoinsId());
		memberBorrow.setTotalReturnNum(totalReturnNum);
		memberBorrow.setBorrowDate(new Date());
		memberBorrow.setReturnedNum(BigDecimal.ZERO);
		memberBorrow.setSurplusNum(totalReturnNum);
		memberBorrow.setBorrowStatus(0);
		//下个月日期
		memberBorrow.setPayBackDate(DateUtil.nextMonth());

		BigDecimal hasBorrow = borrowConfig.getBorrowNum().add(memberBorrowAddReq.getBorrowNum());
		borrowConfig.setBorrowNum(hasBorrow);
		sysBorrowConfigMapper.updateById(borrowConfig);
		memberBorrowMapper.insert(memberBorrow);
		borrowHelp.addBorrowConfigCache(borrowConfig,memberBorrowAddReq.getCoinsId());//库存变化
		return true;
	}

	/**
	 * 获取用户借贷记录列表
	 * @param req
	 * @return
	 */
	@Override
	public CommonPageRep<MemberBorrowDetailsRep> listMemberBorrowByParams(CoinsEnum coin, PageMemberBorrowReq req) {
		Integer userId = sessionUtil.getUser().getUserId();
		Page<MemberBorrow> page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
		List<MemberBorrowDetailsRep> list = memberBorrowMapper.selectList(new LambdaQueryWrapper<MemberBorrow>()
				.eq(MemberBorrow::getMemberId, userId)
				.eq(MemberBorrow::getCoinsId, coin.getCode())
				.orderByDesc(MemberBorrow::getUpdateTime))
				.stream().map(item -> ModelMapperUtil.map(item,MemberBorrowDetailsRep.class))
				.collect(Collectors.toList());
		return CommonPageRep.buildResultRep(page,list);
	}

	/**
	 * 获取用户借贷详情
	 *
	 * @param borrowId
	 * @return
	 */
	@Override
	public MemberBorrowDetailsRep details(Integer borrowId) {
		MemberBorrow memberBorrow = memberBorrowMapper.selectById(borrowId);
		return ModelMapperUtil.map(memberBorrow,MemberBorrowDetailsRep.class);
	}


	/**
	 * 查询获取借款配置
	 * @param coinsId
	 * @return
	 */
	private SysBorrowConfig getBorrowConfig(int coinsId){
		SysBorrowConfig sysBorrowConfig = borrowHelp.getBorrowConfigCache(coinsId);
		if(ObjectUtils.isEmpty(sysBorrowConfig)){
			sysBorrowConfig = sysBorrowConfigMapper.getCoinBorrowConfig(coinsId);
			if(ObjectUtils.isEmpty(sysBorrowConfig)){
				throw new CommonException("借贷配置信息为空，无法执行借贷操作");
			}
			borrowHelp.addBorrowConfigCache(sysBorrowConfig,coinsId);
		}
		return sysBorrowConfig;
	}
}
